<template>
	<div class="expense">
		<div style="display: flex; justify-content: space-between">
			<div style="display: flex">
				<el-button type="primary" @click="add">申请报销</el-button>
				<el-button type="primary" @click="exportExcel" v-debounce>
					导出账单
				</el-button>
				<el-button type="primary" @click="ClickExpenseAll" :disabled="ifExpenseAll && !expenseAll.length">
					{{ ifExpenseAll ? "确认报销" : "一键报销" }}
				</el-button>
				<el-button v-if="ifExpenseAll" type="primary" @click="allClinck">
					{{ this.expenseAll.length == this.tableDataFilter.length ? "取消全选" : "报销全选" }}
				</el-button>
				<el-button v-if="ifExpenseAll" type="primary" @click="closeExpenseAll">
					{{ "取消报销" }}
				</el-button>
				<div class="el-button el-button--primary" v-if="ifExpenseAll">{{
					`总计：${Math.round(expenseAll.reduce((prev, cur) => prev + cur.price, 0) * 100) / 100}`
				}}</div>
			</div>
			<div style="display: flex">
				<el-select v-model="userId" filterable remote :loading="userLoading" clearable placeholder="按申请人搜索"
					@change="getTableData" :remote-method="getUserList"
					v-if="userInfo.roleId === '1' || userInfo.roleId === '5'" @focus="getUserList('')"
					style="margin-left: 10px; width: 200px;">
					<el-option v-for="item in userList" :key="item.id" :label="item.nickName" :value="item.id">
					</el-option>
				</el-select>
				<el-date-picker v-model="selectDate" style="margin-left: 10px;" type="monthrange" range-separator="至"
					start-placeholder="开始月份" end-placeholder="结束月份" @change="getTableData" />
				<el-select v-model="status" style="margin-left: 10px; width: 150px;" @change="getTableData"
					placeholder="按状态">
					<el-option label="待审核" :value="0"></el-option>
					<el-option label="已审核" :value="1"></el-option>
					<el-option label="已报销" :value="3"></el-option>
					<el-option label="被驳回" :value="2"></el-option>
				</el-select>
				<el-button @click="reset" style="margin-left: 10px;" v-debounce>重置</el-button>
			</div>
		</div>

		<div class="goods-table">
			<el-table :data="tableDataFilter" v-loading="loading" border stripe style="width: 100%" height="100%"
				@row-click="tableRowClick">
				<el-table-column prop="i" label="序号" fixed="left" width="50">
				</el-table-column>
				<el-table-column prop="userName" label="申请人" width="80">
				</el-table-column>
				<el-table-column prop="price" label="报销金额" width="80">
				</el-table-column>
				<el-table-column prop="info" label="报销说明" width="250">
				</el-table-column>
				<el-table-column label="附加图" width="115">
					<template slot-scope="scope">
						<el-image style="width: 90px; height: 90px" v-if="scope.row.image != null"
							:src="READ_IMG_URL + scope.row.imageUrl[0]" :preview-src-list="addUrl(scope.row.imageUrl)"
							fit="cover">
						</el-image>
						<el-button type="text" @click="partsOpen(scope.row)" v-else-if="scope.row.purchaseId != null">
							点击查看
						</el-button>
						<span v-else>没有图片</span>
					</template>
				</el-table-column>
				<el-table-column prop="createTime" label="申请时间" width="160">
				</el-table-column>
				<el-table-column prop="status" label="状态" width="80">
					<template slot-scope="scope">
						<div v-if="scope.row.billsStatus === null">
							<el-tag v-if="scope.row.status === 0" type="warning">
								待审核
							</el-tag>
							<el-tag v-if="scope.row.status === 1" type="success">
								已通过
							</el-tag>
							<el-tag v-if="scope.row.status === 2" type="danger">
								被驳回
							</el-tag>
						</div>
						<div v-else>
							<el-tag v-if="scope.row.billsStatus === 0" type="warning">
								待报销
							</el-tag>
							<el-tag v-if="scope.row.billsStatus === 1" type="success">
								已报销
							</el-tag>
							<el-tag v-if="scope.row.billsStatus === 2" type="danger">
								待报销
							</el-tag>
						</div>
					</template>
				</el-table-column>
				<el-table-column prop="remarks" label="备注" fit>
				</el-table-column>
				<el-table-column label="操作" width="100" fixed="right">
					<template slot-scope="scope">
						<div v-if="ifExpenseAll"
							:style="{ color: expenseAll.findIndex(item => scope.row.id == item.id) < 0 ? 'gray' : 'skyblue' }">
							{{ expenseAll.findIndex(item => scope.row.id == item.id) < 0 ? "未选择" : "已选择" }}</div>
								<el-button v-else :type="examineType(scope.row)" size="mini"
									:disabled="examineDisabled(scope.row)" @click="examineDialog(scope.row)">
									{{ examineText(scope.row) }}
								</el-button>
					</template>
				</el-table-column>
			</el-table>
			<el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
				:current-page="currentPage" :page-sizes="[20, 50, 100]" :page-size="pageSize"
				layout="total, sizes, prev, pager, next, jumper" :total="total">
			</el-pagination>
		</div>
		<!-- 查看零件列表弹窗 -->
		<el-dialog style="margin-top:0" :visible.sync="partsShow" width="85%" :title="selectTitle" @close="partsClose">
			<div class="data-table">
				<el-table :data="selectPartList" border stripe style="width: 100%" :max-height="500">
					<el-table-column prop="i" fixed="left" label="序号" width="50">
					</el-table-column>
					<el-table-column label="图片" width="115">
						<template slot-scope="scope">
							<el-image :src="READ_IMG_URL + scope.row.image" style="width: 90px; height: 90px;"
								:preview-src-list="new Array(READ_IMG_URL + scope.row.image)">
							</el-image>
						</template>
					</el-table-column>
					<el-table-column prop="partName" label="零件名称" fit>
					</el-table-column>
					<el-table-column prop="model" label="零件型号" fit>
					</el-table-column>
					<el-table-column prop="devicesDescribe" label="产品描述" fit>
					</el-table-column>
					<el-table-column prop="remark" label="备注" fit>
					</el-table-column>
					<el-table-column prop="purchasePrice" label="采购单价" width="80">
					</el-table-column>
					<el-table-column prop="freight" label="运输费" width="80">
					</el-table-column>
					<el-table-column prop="isIncludeTax" label="是否含税" width="80">
						<template slot-scope="scope">
							<el-tag v-if="scope.row.isIncludeTax === 0">含税</el-tag>
							<el-tag v-if="scope.row.isIncludeTax === 1" type="danger">
								不含税
							</el-tag>
						</template>
					</el-table-column>
					<el-table-column prop="partCount" label="采购数量" width="80">
					</el-table-column>
					<el-table-column prop="totalPrice" label="总计" width="80">
					</el-table-column>
				</el-table>
			</div>
		</el-dialog>
		<!-- 报销审核弹窗 -->
		<el-dialog :visible.sync="expenseDialogShow" width="75%" title="报销审核" @close="expenseDialogClose">
			<el-form label-position="top" inline :model="selectExpense">
				<el-form-item label="申请人" style="width: 500px;">
					<el-input :value="selectExpense.userName" readonly>
					</el-input>
				</el-form-item>
				<el-form-item label="报销金额" style="width: 500px;">
					<el-input :value="selectExpense.price" readonly>
					</el-input>
				</el-form-item>
				<el-form-item label="报销说明" prop="info" style="width: 500px;">
					<el-input type="textarea" :value="selectExpense.info" readonly
						:autosize="{ minRows: 4, maxRows: 6 }" placeholder="报销说明">
					</el-input>
				</el-form-item>
				<el-form-item label="备注" style="width: 500px;">
					<el-input :value="selectExpense.remarks" type="textarea" readonly
						:autosize="{ minRows: 4, maxRows: 6 }" placeholder="备注">
					</el-input>
				</el-form-item>
				<el-form-item label="附加图" class="elFormItem">
					<div v-if="selectExpense.image != null">
						<el-image class="expenseImg" fit="cover" v-for="(item, index) in selectExpense.imageUrl"
							:key="index" :src="READ_IMG_URL + item" :preview-src-list="addUrl(selectExpense.imageUrl)">
						</el-image>
					</div>
					<div class="data-table" v-else style="width: 100%">
						<el-table :data="selectPartList" border stripe style="width: 100%" :max-height="500">
							<el-table-column prop="i" fixed="left" label="序号" width="50">
							</el-table-column>
							<el-table-column label="图片" width="115">
								<template slot-scope="scope">
									<el-image :src="READ_IMG_URL + scope.row.image" style="width: 90px; height: 90px;"
										:preview-src-list="new Array(READ_IMG_URL + scope.row.image)">
									</el-image>
								</template>
							</el-table-column>
							<el-table-column prop="partName" label="零件名称" fit>
							</el-table-column>
							<el-table-column prop="model" label="零件型号" fit>
							</el-table-column>
							<el-table-column prop="devicesDescribe" label="产品描述" fit>
							</el-table-column>
							<el-table-column prop="remark" label="备注" fit>
							</el-table-column>
							<el-table-column prop="purchasePrice" label="采购单价" width="80">
							</el-table-column>
							<el-table-column prop="freight" label="运输费" width="80">
							</el-table-column>
							<el-table-column prop="isIncludeTax" label="是否含税" width="80">
								<template slot-scope="scope">
									<el-tag v-if="scope.row.isIncludeTax === 0">含税</el-tag>
									<el-tag v-if="scope.row.isIncludeTax === 1" type="danger">
										不含税
									</el-tag>
								</template>
							</el-table-column>
							<el-table-column prop="partCount" label="采购数量" width="80">
							</el-table-column>
							<el-table-column prop="totalPrice" label="总计" width="80">
							</el-table-column>
						</el-table>
					</div>
				</el-form-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button type="danger" @click="examine(2)" v-debounce>不通过</el-button>
				<el-button type="success" @click="examine(1)" v-debounce>通过</el-button>
			</div>
		</el-dialog>
		<!-- 财务报销弹窗 -->
		<el-dialog :visible.sync="paymentDialogShow" width="60%" title="财务报销" @close="paymentDialogClose">
			<el-form label-position="top" inline>
				<el-form-item label="申请人" style="width: 450px;">
					<el-input :value="selectExpense.userName" readonly>
					</el-input>
				</el-form-item>
				<el-form-item label="报销金额" style="width: 450px;">
					<el-input v-model="expenseBilling.amountPayable">
					</el-input>
				</el-form-item>
				<el-form-item label="付款账户" style="width: 450px;">
					<el-select v-model="accountId" filterable remote clearable placeholder="按账户搜索" style="width: 100%;"
						:remote-method="getAccountList" @focus="getAccountList('')" >
						<el-option v-for="item in accountList" :key="item.id" :label="item.account" :value="item.id">
						</el-option>
					</el-select>
				</el-form-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="paymentDialogShow = false">取消</el-button>
				<el-button type="success" @click="payment" v-debounce>报销</el-button>
			</div>
		</el-dialog>

		<el-dialog :visible.sync="accountDialogShow" @close="paymentDialogClose" title="一键报销">
			<el-form label-position="top" inline>
				<el-form-item label="付款账户" style="width: 100%;">
					<el-select v-model="accountId" filterable remote clearable placeholder="按账户搜索" style="width: 100%"
						:loading="accountLoading" :remote-method="getAccountList" @focus="getAccountList('')"
						popper-class="eloption">
						<el-option v-for="item in accountList" :key="item.id" :label="item.account" :value="item.id">
						</el-option>
					</el-select>
				</el-form-item>
				<el-from-item label="总计" style="width: 100%;">
					<div>{{ `总计：${expenseAll.reduce((prev, cur) => prev + cur.price, 0).toFixed(2)}` }}</div>
				</el-from-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="() => (accountDialogShow = false, accountId = void 0)">取消</el-button>
				<el-button type="success" @click="paymentAll" v-debounce>报销</el-button>
			</div>
		</el-dialog>
	</div>
</template>

<script>
import financeApi from '../../api/financeManage';
import warehouseApi from '../../api/warehouse';
import userApi from '../../api/user';
import config from '../../api/apiURL.js';
export default {
	data() {
		return {
			READ_IMG_URL: config.READ_IMG_URL,
			userInfo: {},
			tableData: [],
			loading: false,
			currentPage: 1,
			pageSize: 50,
			total: 0,
			userId: null,
			selectDate: void 0,
			status: null,
			selectExpense: {},
			expenseDialogShow: false,
			userLoading: false,
			userList: [],
			paymentDialogShow: false,
			expenseBilling: {},
			accountId: null,
			accountLoading: false,
			accountList: [],
			partsShow: false,
			selectTitle: "",
			selectPartList: [],
			ifExpenseAll: false,
			expenseAll: new Array(),
			accountDialogShow: false,
            options: [{
                value: '选项1',
                label: '黄金糕'
                }, {
                value: '选项2',
                label: '双皮奶'
                }, {
                value: '选项3',
                label: '蚵仔煎'
                }, {
                value: '选项4',
                label: '龙须面'
                }, {
                value: '选项5',
                label: '北京烤鸭'
                },{
                value: '选项1',
                label: '黄金糕'
                },{
                value: '选项1',
                label: '黄金糕'
                },{
                value: '选项1',
                label: '黄金糕'
                },{
                value: '选项1',
                label: '黄金糕'
                },{
                value: '选项1',
                label: '黄金糕last'
                },],
            value: ''
        }
	},
	created() {
		this.userInfo = JSON.parse(localStorage.getItem("userInfo"))
		this.getTableData();
	},
	computed: {
		tableDataFilter() {
			return this.ifExpenseAll ? this.tableData.filter(item => item.billsStatus == 0) : this.tableData
		}
	},
	methods: {
		// 获取表格数据
		getTableData() {
			this.loading = true;
			this.tableData = new Array();
			const data = {
				userId: this.userId,
				status: this.status == 3 ? 1 : this.status,
				currentPage: this.currentPage,
				pageSize: this.pageSize,
				billsStatus: this.status % 2 == 1 ? parseInt((this.status - 1) / 2) : null,
				dateStart: Array.isArray(this.selectDate) ?
					(this.selectDate[0].getFullYear() + "-" +
						((this.selectDate[0].getMonth() + 1) < 10 ?
							'0' + (this.selectDate[0].getMonth() + 1) :
							this.selectDate[0].getMonth() + 1) + "-"
						+ "01 00:00:00") : void 0,
				dateEnd: Array.isArray(this.selectDate) ?
					(this.selectDate[1].getFullYear() + "-" +
						((this.selectDate[1].getMonth() + 1) < 10 ?
							'0' + (this.selectDate[1].getMonth() + 1) :
							this.selectDate[1].getMonth() + 1) + "-"
						+ "01 00:00:00") : void 0
			}
			warehouseApi.getExpenseList(data).then(res => {
				if (res.code === 200) {
					this.total = res.data.total;
					this.tableData = res.data.expenseVoList.map((item, index) => {
						item.i = (this.currentPage - 1) * this.pageSize + index + 1
						return item;
					})
				}
			}).finally(() => {
				this.loading = false;
			})
		},
		// pageSize变化
		handleSizeChange(pageSize) {
			this.pageSize = pageSize;
			this.getTableData();
		},
		// 页码变化
		handleCurrentChange(curPage) {
			this.currentPage = curPage;
			this.getTableData();
		},
		// 申请报销
		add() {
			this.$router.push({
				path: "/expense/addExpense"
			})
		},
		// 远程搜索用户
		getUserList(query) {
			this.userLoading = true;
			const data = {
				nickName: query,
			}
			userApi.fuzzyQuery(data).then(res => {
				if (res.code === 200) {
					this.userList = res.data.userVoList;
				}
			}).finally(() => {
				this.userLoading = false;
			})
		},
		// 重置
		reset() {
			this.userId = null;
			this.status = null;
			this.currentPage = 1;
			this.selectDate = void 0
			this.getTableData();
		},
		// 审核按钮类型
		examineType(row) {
			if (row.billsStatus === null) {
				if (row.status === 1) {
					return "success"
				} else if (row.status === 2) {
					return "danger"
				}
				return "warning"
			} else {
				if (row.billsStatus === 1) {
					return "success"
				} else if (row.billsStatus === 2) {
					return "danger"
				}
				return "warning"
			}
		},
		// 审核按钮禁用
		examineDisabled(row) {
			if (row.billsStatus === null) {
				if (this.userInfo.roleId === '1' && row.status === 0) {
					return false;
				} else if (row.status === 2) {
					return false;
				}
				return true;
			} else {
				if ((this.userInfo.roleId === '1' || this.userInfo.roleId === '6') &&
					row.billsStatus === 0) {
					return false;
				} else if (row.billsStatus === 2) {
					return false;
				}
				return true;
			}
		},
		// 审核按钮文字
		examineText(row) {
			if (row.billsStatus === null) {
				if (row.status === 1) {
					return "已通过"
				} else if (row.status === 2) {
					return "被驳回"
				}
				return "待审核"
			} else {
				if (row.billsStatus === 1) {
					return "已报销"
				}
				return "待报销"
			}
		},
		addUrl(list) {
			let newList = []
			list.forEach(item => {
				newList.push(this.READ_IMG_URL + item)
			})
			return newList;
		},
		// 打开审核按钮弹窗
		examineDialog(row) {
			if (row.billsStatus === 0) {
				this.selectPartList = row.partList?.map((part, index) => {
					part.i = index + 1;
					return part;
				}) ?? new Array();
			}
			if (row.billsStatus === null) {
				if (row.status === 2) {
					localStorage.setItem("expenseId", row.id)
					this.$router.push({
						path: '/expense/addExpense'
					})
				} else {
					this.selectExpense = row;
					this.selectPartList = row.partList?.map((part, index) => {
						part.i = index + 1;
						return part;
					});
					this.expenseDialogShow = true;
				}
			} else {
				if (row.billsStatus !== 1) {
					this.selectExpense = row;
					this.getExpenseBilling(row);
				}
			}
		},
		partsOpen(row) {
			this.selectPartList = row.partList.map((part, index) => {
				part.i = index + 1;
				return part;
			});
			this.selectTitle = row.userName;
			this.partsShow = true;
		},
		// 零件列表关闭
		partsClose() {
			this.selectPartList = []
			this.selectTitle = ""
		},
		// 审核弹窗关闭
		expenseDialogClose() {
			this.selectPartList = []
			this.selectExpense = {}
			this.partsClose()
		},
		// 审核
		examine(index) {
			let msg = ""
			if (index === 1) {
				msg = "是否要通过？"
			} else if (index === 2) {
				msg = "是否要驳回？"
			}
			this.$confirm(msg, "提示", {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning'
			}).then(() => {
				const data = {
					id: this.selectExpense.id,
					status: index
				}
				warehouseApi.examineExpense(data).then(res => {
					if (res.code === 200) {
						this.$message.success("操作成功");
						this.selectExpense = {};
						this.expenseDialogShow = false;
						this.getTableData();
					}
				})
			})
		},
		// 根据报销单获取账单
		getExpenseBilling(item) {
			const data = {
				orderId: item.id
			}
			financeApi.getExpenseBilling(data).then(res => {
				if (res.code === 200) {
					this.expenseBilling = res.data;
					this.paymentDialogShow = true;
				}
			})
		},
		paymentDialogClose() {
			this.accountId = null;
			this.expenseBilling = {}
			this.selectExpense = {}
		},
		// 远程搜索账户
		getAccountList(query) {
			this.accountLoading = true;
			const data = {
				accountName: query,
				currentPage: 1,
				pageSize: 999,
			}
			financeApi.getAccountList(data).then(res => {
				if (res.code === 200) {
					this.accountList = res.data.accountList
				}
			}).finally(() => {
				this.accountLoading = false;
			})
		},
		// 账单报销
		payment() {
			if (this.accountId === null) {
				this.$message.error("请选择账户")
				return;
			}
			this.$confirm("确定要报销该账单吗？", "提示", {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning'
			}).then(() => {
				const loading = this.$loading({
					lock: true,
					text: 'Loading...',
					spinner: 'el-icon-loading',
					background: 'rgba(0, 0, 0, 0.7)'
				});
				const data = {
					id: this.expenseBilling.id,
					account: this.accountId,
					amountPayable: this.expenseBilling.amountPayable
				}
				financeApi.paymentExpenseBilling(data).then(res => {
					if (res.code === 200) {
						this.$message.success("报销成功");
						this.paymentDialogShow = false;
						this.getTableData();
					}
				}).finally(() => {
					loading.close();
				})
			})
		},
		//导出Excel
		exportExcel() {
			const data = this.formatData(this.tableData); // 将数据格式化为xlsx可以识别的格式
			const wb = this.$XLSX.utils.book_new();
			const ws = this.$XLSX.utils.json_to_sheet(data);
			// 设置列宽
			const columnWidths = [
				{ wch: 5 }, // 序号
				{ wch: 10 }, // 申请人
				{ wch: 10 }, // 报销金额
				{ wch: 30 }, // 报销说明
				{ wch: 20 }, // 申请时间
				{ wch: 20 }, // 备注
				{ wch: 30 } // 附加图
			];
			ws['!cols'] = columnWidths;
			this.$XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
			this.$XLSX.writeFile(wb, "报销申请.xlsx");
		},
		formatData(data) {
			// 格式化表格数据，将对象数组转换为数组对象
			return data.map((item) => {
				const {
					i,
					userName,
					price,
					info,
					createTime,
					remark,
					image,
				} = item;
				return {
					序号: i,
					申请人: userName,
					报销金额: price,
					报销说明: info,
					申请时间: createTime,
					备注: remark,
					附加图: image,
				};
			});
		},
		ClickExpenseAll() {
			if (this.ifExpenseAll) {
				this.accountDialogShow = true
			} else {
				this.ifExpenseAll = true
			}
		},
		tableRowClick(row) {
			if (this.ifExpenseAll) {
				this.expenseAll.findIndex(item => item.id == row.id) < 0 ? this.expenseAll.push(row) : this.expenseAll.pop(row)
			}
		},
		paymentAll() {
			const loading = this.$loading({
				lock: true,
				text: 'Loading...',
				spinner: 'el-icon-loading',
				background: 'rgba(0, 0, 0, 0.7)'
			})
			const accountClone = structuredClone(this.accountId)
			Promise.all(
				this.expenseAll.map(async item => {
					const data = {
						orderId: item.id
					}
					const res = await financeApi.getExpenseBilling(data)
					const dataP = {
						id: res.data.id,
						account: accountClone
					}
					financeApi.paymentExpenseBilling(dataP)
				})
			).then(() => {
				this.paymentDialogShow = false;
			}).finally(() => {
				loading.close();
				this.ifExpenseAll = false
				this.accountDialogShow = false
				this.expenseAll = new Array()
				this.getTableData()
			})
		},
		closeExpenseAll() {
			this.ifExpenseAll = false
			this.expenseAll = new Array()
		},
		allClinck() {
			if (this.expenseAll.length == this.tableDataFilter.length) {
				this.expenseAll = new Array()
			} else {
				this.expenseAll = structuredClone(this.tableDataFilter)
			}
		}
	},
};
</script>

<style scoped>
.expense {
	height: 100%;
}

.goods-table {
	height: 94%;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	justify-content: center;
	margin-top: 10px;
}

.expenseImg {
	width: 150px;
	height: 150px;
	margin-right: 10px;
}

.elFormItem {
	width: 100% !important;
}
</style>

<style>
.eloption .el-select-dropdown__wrap {
	max-height: 120px !important;
}
</style>